package rsj.service.contract;

import com.alibaba.fastjson.JSON;
import com.rlyy.aibase.utils.base.Node;
import com.rlyy.aibase.utils.base.TableNode;
import common.exec.RsjIllegalArgueException;
import common.statusenum.ServiceStatusEnum;
import common.statusenum.StatusEnum;
import common.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import rsj.api.contract.entity.Contract;
import rsj.api.contract.entity.ContractDetail;
import rsj.api.contract.entity.ContractStatistic;
import rsj.service.product.IProductService;
import rsj.service.stat.IStatService;
import rsj.service.user.IUserService;
import rsj.sql.contract.ContractDao;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 合同
 *
 * @author yuanqinglong
 * @since 2021/7/16 16:56
 */
@Service
public class ContractServiceImpl implements IContractService {

    /**
     * 合同dao
     */
    @Autowired
    private ContractDao contractDao;

    @Autowired
    private IStatService statServiceImpl;

    @Autowired
    private IUserService userServiceImpl;

    @Autowired
    private IProductService productServiceImpl;


    /**
     * 合同列表
     *
     * @param orgId    机构id
     * @param pageSize 页面大小
     * @param pageNow  页面现在
     * @return {@link List<Contract>}
     */
    @Override
    public List<ContractDetail> contractList(String orgId, Integer pageSize, Integer pageNow) {
        TableNode contractList = contractDao.contractList(orgId, pageSize, pageNow);
        List<ContractDetail> contracts = JSON.parseArray(contractList.toJson(), ContractDetail.class);
        // 合同id
        List<String> orgpIds = contracts.stream().map(ContractDetail::getOrgpId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(orgpIds)) {
            return contracts;
        }
        // 查询 统计表 合同下产品的使用情况
        List<ContractStatistic> contractStatistics = statServiceImpl.statisticContractUsage(orgpIds);
        // 按照合同id分组、再按照合同下产品编号为key转Map
        Map<String, Map<String, ContractStatistic>> contractProductMap = contractStatistics.stream().collect(Collectors.groupingBy(ContractStatistic::getStatOrgpId, Collectors.toMap(ContractStatistic::getStatProdUid, Function.identity())));
        contracts.forEach(contract -> contract.calculateProductUsage(contractProductMap.get(contract.getOrgpId())));
        return contracts;
    }


    /**
     * 合同数
     *
     * @param orgId 机构id
     * @return int
     */
    @Override
    public int contractCount(String orgId) {
        return contractDao.contractCount(orgId).valueInt();
    }


    /**
     * 添加合同
     *
     * @param contract 合同
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addContract(Contract contract) {
        contract.initializeAddProperties();
        Node node = contractDao.checkContractCanCreate(contract.getOrgpOrgId(), contract.getOrgpProdId(), contract.getOrgpContractime());
        Assert.isTrue(node.valueInt() == 0, "相同的批次一天只能创建一次");
        contractDao.addContract(contract);
        // 2021/8/20 更新已申请的合同状态
        // 2021/8/20 更新产品销量字段
        String[] prods = contract.getOrgpProdId().split(",");
        for (String prodId : prods) {
            contractDao.changeAppliedStatus(contract.getOrgpOrgId(), ServiceStatusEnum.APPLICATION_PROCESSED_CODE, prodId, LocalDateTime.now());
            productServiceImpl.updateProductSales(1, prodId);
        }
    }

    /**
     * 检查合同中产品的使用
     *
     * @param orgId   机构 id
     * @param prodUid 产品编号
     * @return {@link List<String>}
     */
    @Override
    public List<String> checkContractedProduct(String orgId, String prodUid) {
        TableNode tableNode = contractDao.checkContractedProduct(orgId, prodUid);
        List<Contract> contracts = JSON.parseArray(tableNode.toJson(), Contract.class);
        return contracts.stream().map(Contract::getOrgpId).collect(Collectors.toList());
    }

    /**
     * 更新合同状态
     *
     * @param orgpId 合同id
     * @param status 合同状态（0停用、1启用）
     */
    @Override
    public void updateContractStatus(String orgpId, String status) {
        // 启用合同 判断创建合同的账号是否停用
        if (Objects.equals(StatusEnum.YES.getCode(), status)) {
            String contractUserStatus = userServiceImpl.getContractUserStatus(orgpId);
            if (!Objects.equals(StatusEnum.YES.getCode(), contractUserStatus)) {
                throw new RsjIllegalArgueException("合同账号已停用、合同不可启用");
            }
        }
        contractDao.updateContractStatus(orgpId, status);
    }

    /**
     * 合同组织
     *
     * @param orgId org id
     * @return {@link List<String>}
     */
    @Override
    public List<String> contractUnderOrganization(String orgId) {
        TableNode underOrganization = contractDao.contractUnderOrganization(orgId);
        List<Contract> contracts = JSON.parseArray(underOrganization.toJson(), Contract.class);
        return contracts.stream().map(Contract::getOrgpId).collect(Collectors.toList());
    }

    /**
     * 组合包量合同
     *
     * @param orgIds 机构id
     * @return {@link List<Contract>}
     */
    @Override
    public List<Contract> combinationContract(List<String> orgIds) {
        TableNode tableNode = contractDao.combinationContract(orgIds);
        return JSON.parseArray(tableNode.toJson(), Contract.class);
    }
}
